package resilienceManager.qmul.gemom;



import java.awt.*;
import java.awt.event.*;
import java.util.Date;
import java.util.Enumeration;
import java.util.TimerTask;
import java.util.Timer;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;

import cbr.resilienceManager.qmul.gemom.CbrData;
import cbr.resilienceManager.qmul.gemom.CbrSaving;

import mo.qmul.gemom.publisher;
import no.geosoft.cc.geometry.Geometry;
import no.geosoft.cc.geometry.Matrix4x4;
import no.geosoft.cc.graphics.*;


/**
 * Auction Frame
 *  
 * COPYRIGHT DISCLAIMER
 * Synopsis: All the source codes presented in this document are intellectual
 * properties of Queen Mary, University of London.
 * 
 * @year 2010
 * @author Peng Jiang, John Bigham, Jiayi Wu Jinfu Wang------------QMUL
 * @version 1.0 
 */
  

public class AuctionFrame extends JFrame{
	// used for the item draw
	private GScene  scene_1;

	// used for the bidder draw
	private GScene  scene_2;

	private JTree bidTree;
	JTabbedPane tabbedPane;

	private NSitem[] items;
	private Gbroker[] gblist;
	private int bgID;


	// used for the bid tree search
	private BidTree bid;
	private JTree searchTree;

	// used for the star search
	private starSearch star;
	private JTree starTree;
	private JTree starsearchTree;


	// used for the thread 
	private JPanel ThreadPanel;
	private ViewCanvas vc;
	private ThreadControlPanel tcp;
	private JTree threadTree;


	// used for the case based reasoning
	public CbrData cd;
	
	private boolean newCase;
	
	
	// used for the information publication to over layer manager
	
	private String[] solution;


	public AuctionFrame(NSitem[] its, Gbroker[] gb, CbrData _cd, boolean cased){

		super ("Re-allocation Control");
		
		

		// set the items 
		this.items=new NSitem[its.length];
		this.items=its.clone();

		this.gblist=new Gbroker[gb.length];
		this.gblist=gb.clone();

		this.bgID=_cd.getTableID();
		
		this.cd=_cd;
		this.newCase=cased;

		
		
		
		//set the menu bar
		MenuBar mb=new MenuBar();
		setMenuBar(mb); 
		
		// set the Submit menu
		Menu fm= new Menu("Submit");
		mb.add(fm);
		MenuItem mi;

		// publish menu item
		fm.add(mi = new MenuItem("publish", new MenuShortcut('O')));
		mi.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
				String[] gString= new String[gblist.length];
				
				
				
				for(int i=0; i< gblist.length; i++)
				{
					gString[i]="Gbroker-"+gblist[i].getID();
				}
				
				if(newCase)
				{
					solution = new String[gblist.length];
					solution=cd.getSoultion();
				
				}
			
				publisher p= new publisher(gString, solution);
				p.show();
				
			}
		}
		);
		
		
		


		// create the panel for the button
		JPanel buttonPanel = new JPanel(new GridLayout(3, 3)); 

		//XXX start button and action
		JButton startButton = new JButton("Generate Bid Tree");
		startButton.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(ActionEvent event) {
				Date now = new Date(System.currentTimeMillis());

				System.out.println(now.toLocaleString());
				
//XXX ini bid tree  
				startAction();

				Date finish = new Date(System.currentTimeMillis());

				System.out.println(finish.toLocaleString());


			}
		});
		buttonPanel.add(startButton);


		// reset buttion and action
		JButton resetButton = new JButton("Bid Tree Search");
		resetButton.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(ActionEvent event) {
//XXX search bid tree
				searchAction();

			}
		});
		buttonPanel.add(resetButton);



		//A star  button
		JButton AButton = new JButton("Generate A* Tree");
		AButton.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(ActionEvent event) {
				Date now = new Date(System.currentTimeMillis());

				System.out.println(now.toLocaleString());
//XXX generate a* tree
				astarAction();

				Date finish = new Date(System.currentTimeMillis());

				System.out.println(finish.toLocaleString());


			}
		});
		buttonPanel.add(AButton);


		//A star search  button
		JButton AsButton = new JButton("A* search");
		AsButton.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(ActionEvent event) {
//XXX a* search
				starsearchAction();
			}
		});
		buttonPanel.add(AsButton);


		// distributed approach for all thread star
		JButton allstartButton= new JButton("All start");
		allstartButton.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(ActionEvent event) {

				startAll();


			}
		});
		buttonPanel.add(allstartButton);

		// all thread stop for distributed approach
		JButton allstopButton= new JButton("All stop");
		allstopButton.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(ActionEvent event) {

				stopAll();

			}
		});
		buttonPanel.add(allstopButton);


		// add the buttion panel in the frame
		add (buttonPanel,   BorderLayout.SOUTH);

		// Create the graphic canva
		tabbedPane = new JTabbedPane();

		GWindow window1 = new GWindow();

		tabbedPane.addTab("Items", window1.getCanvas());

		GWindow window2 = new GWindow();
		tabbedPane.addTab("Bidders", window2.getCanvas());



		// create the tree scroll pane for the bidder tree show
		JScrollPane scrollPane1 = new JScrollPane();


		DefaultMutableTreeNode top = new DefaultMutableTreeNode("Bid");
		bidTree = new JTree(top);
		scrollPane1.getViewport().add(bidTree);

		tabbedPane.addTab("Bid Tree", scrollPane1);


		// A star tree
		JScrollPane scrollPane3 = new JScrollPane();


		DefaultMutableTreeNode top3 = new DefaultMutableTreeNode("A*");
		starTree = new JTree(top3);
		scrollPane3.getViewport().add(starTree);

		tabbedPane.addTab("A* Tree", scrollPane3);


		// create the auction result 
		JScrollPane scrollPane2 = new JScrollPane();


		DefaultMutableTreeNode top1 = new DefaultMutableTreeNode("Search");
		searchTree = new JTree(top1);
		scrollPane2.getViewport().add(searchTree);

		tabbedPane.addTab("Bid Tree Solutions", scrollPane2);

		// create the auction result 
		JScrollPane scrollPane4 = new JScrollPane();


		DefaultMutableTreeNode top4 = new DefaultMutableTreeNode("Search");
		starsearchTree = new JTree(top4);
		scrollPane4.getViewport().add(starsearchTree);

		tabbedPane.addTab("A* Solution", scrollPane4);



		// Create scene with default viewport and world extent settings
		scene_1 = new GScene (window1, "Scene1");
		scene_2 = new GScene (window2, "Scene2");

		double w0[] = {0.0,    1200.0, 0.0};
		double w1[] = {1200.0, 1200.0, 0.0};
		double w2[] = {0.0,       0.0, 0.0};    
		scene_1.setWorldExtent (w0, w1, w2);



		double w3[] = {0.0,    1200.0, 0.0};
		double w4[] = {1200.0, 1200.0, 0.0};
		double w5[] = {0.0,       0.0, 0.0};    
		scene_2.setWorldExtent (w3, w4, w5);


		GStyle style1 = new GStyle();
		style1.setForegroundColor (new Color (0, 0, 0));
		style1.setBackgroundColor (new Color (255, 255, 255));
		style1.setFont (new Font ("Dialog", Font.BOLD, 12));
		scene_1.setStyle (style1);

		GStyle style2 = new GStyle();
		style2.setForegroundColor (new Color (0, 0, 255));
		style2.setBackgroundColor (new Color (255, 255, 255));
		style2.setFont (new Font ("Dialog", Font.BOLD, 12));
		scene_2.setStyle (style2);


		ItemSetup();
		window1.refresh();

		bidderSetup();
		window2.refresh();
		



		/// create the search thread
		// the number of thread
		int nthreads=gblist.length;

		Object monitor = new Object();
		starThread[] threads = new starThread[nthreads];
		for ( int i = 0; i < nthreads; i++ )
			threads[i] = new starThread(items,gblist, bgID, i);// set the thread ID from 0

		// setup the panel
		ThreadPanel= new JPanel();

		ThreadPanel.setBackground(Color.white);
		ThreadPanel.setLayout(new BorderLayout());

		vc=new ViewCanvas(threads);
		ThreadPanel.add(vc,BorderLayout.CENTER);

		tcp= new ThreadControlPanel(threads,gblist);
		ThreadPanel.add(tcp,BorderLayout.SOUTH);

		TimerTask tasks= new  TimerTask(){
			public void run(){ 
				vc.repaint(); 
				tcp.repaint(); 
			}
		};

		Timer timer=new Timer();

		// set the schedule of the task 
		timer.schedule(tasks,0,1000);

		tabbedPane.addTab("Distributed Search", ThreadPanel);



		// create the thread tree panle
		JScrollPane scrollPane_Thread = new JScrollPane();


		DefaultMutableTreeNode top_thread = new DefaultMutableTreeNode("Distributed");
		threadTree = new JTree(top_thread);
		scrollPane_Thread.getViewport().add(threadTree);
		// set the JTree to the thread control panel
		tcp.setTree(threadTree,tabbedPane);

		tabbedPane.addTab("Distributed Tree", scrollPane_Thread);




		tabbedPane.setSelectedIndex(0);
		add(tabbedPane, BorderLayout.CENTER);
		
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

		setSize (new Dimension (700, 700));
		setVisible (true);

	}


	/**
	 * To draw the combination item 
	 * **/
	private void ItemSetup()
	{
		int item_num=this.items.length;

		boolean drawNS=true;

		if(item_num>10)
		{
			drawNS=false;
		}

		int x_step = 1200/item_num;

		for(int i=0; i<item_num; i++)
		{
			//int id=i+1;
			int id=items[i].getID()+1;
			double x_item=x_step*i+0.01*x_step;
			RectObject nt=new RectObject ("Item"+id,scene_1, x_item, 150,120,60);
			nt.draw();
			NSitem item_temp=items[i];

			// if there are too many items, not draw the name space
			if(drawNS){	
				for(int j=0; j<item_temp.nslist.size();j++)
				{
					double x_node=x_step*i+0.01*x_step+60;
					int y_node=250+j*50+90;
					NodeObject n2=new NodeObject (""+item_temp.nslist.get(j),nt, x_node, y_node,0.7 );
				}// end for
			} // end if drawNS				
		}



		scene_1.refresh();

	}

	/**
	 * to draw the bidders 
	 * **/
	private void bidderSetup()
	{
		int gnum=gblist.length;

		int x_step = 1200/gnum;
		
		String[] text = null;
		
		if(newCase){
			System.out.println("CBR");
			text=cd.getSoultion();
		}

		for(int i=0; i<gnum; i++)
		{
			int bid=i+1;
			double x_item=x_step*i+0.2*x_step;

			RectObject nt=new RectObject ("Bidder"+bid,scene_2, x_item, 150,150,60);

			nt.draw();

			int gid=gblist[i].getID();
			double x_node=x_step*i+0.2*x_step+75;
			int y_node=250+1*50+90;
			NodeObject n2=new NodeObject ("G"+gid,nt, x_node, y_node,gblist[i].getCAP());

			n2.draw();
			
			
			if(newCase){
				
				RectObject n3=new RectObject (text[i],scene_2, x_item, 650,150,60);
				
				n3.draw();
				
			}
			

		}
		
		if(newCase){
			
			gline line1= new gline("CBR",scene_2,110,250,1200);
			gline line2= new gline("Utility="+cd.getRisk(),scene_2,100,360,1200);

			line1.draw();
			line2.draw();

		}


		scene_2.refresh();

	}
	
	// the action used for the case based reasoning
	// similar as the function "searchAction"
	private void caseAction(){
		
		int gnum=gblist.length;

		int x_step = 1200/gnum;
		
		String[] text=cd.getSoultion();
		
		for(int i=0; i<gnum; i++)
		{
			double x_item=x_step*i+0.2*x_step;
			RectObject nt=new RectObject (text[i],scene_2, x_item, 650,150,60);
			// draw the allocation
			nt.draw();
		}
		
		
		
		scene_2.refresh();
	
	
	
	}
//XXX genearte bid tree
	private void startAction(){

		bid=new BidTree(items,gblist, bgID);


		bid.buildTree();
		

		DefaultMutableTreeNode root= bid.getBidTree();

		DefaultTreeModel tmodel=new DefaultTreeModel(root);
		
		

		bidTree.setModel(tmodel);

		expandAll(bidTree, new TreePath(root),true);

		tabbedPane.setSelectedIndex(2);



	}

	// the action for the A star button
	private void astarAction(){
		//build the a star tree
		star= new starSearch(items,gblist, bgID);

		star.buildTree();

		DefaultMutableTreeNode root2= star.getBidTree();

		DefaultTreeModel tmodel2=new DefaultTreeModel(root2);

		starTree.setModel(tmodel2);

		expandAll(starTree, new TreePath(root2),true);

		tabbedPane.setSelectedIndex(3);


	}

	// the action for the A star search button
	private void starsearchAction(){


		DefaultMutableTreeNode root= star.SearchTree();

		DefaultTreeModel tmodel=new DefaultTreeModel(root);

		starsearchTree.setModel(tmodel);

		expandAll(starsearchTree, new TreePath(root),true);


		int gnum=gblist.length;

		int x_step = 1200/gnum;

		DefaultMutableTreeNode currentnode=root;
		
		solution= new String[gnum];
		
		for(int i=0; i<gnum; i++)
		{
			double x_item=x_step*i+0.2*x_step;

			DefaultMutableTreeNode inode=(DefaultMutableTreeNode) currentnode.getChildAt(0);

			RectObject nt=new RectObject (inode.toString(),scene_2, x_item, 950,150,60);

			// save the allocation
			solution[i]=inode.toString();
			
			nt.draw();

			currentnode=inode;
		}
		
		cd.setRisk((float) star.risk_sl);
		CbrSaving.saveState(cd);
		CbrSaving.saveSolution(solution, cd);



		gline line1= new gline("Solution generated by time constraint A star",scene_2,180,450,1200);

		gline line2= new gline("Utility="+star.risk_sl,scene_2,100,530,1200);

		line1.draw();
		line2.draw();

		scene_2.refresh();


		tabbedPane.setSelectedIndex(5);

	}

	// the action for the bid tree search action
	private void searchAction(){
		DefaultMutableTreeNode root= bid.SearchTree();

		DefaultTreeModel tmodel=new DefaultTreeModel(root);

		searchTree.setModel(tmodel);

		expandAll(searchTree, new TreePath(root),true);

		int gnum=gblist.length;

		int x_step = 1200/gnum;

		DefaultMutableTreeNode currentnode=root;

		solution= new String[gnum];

		for(int i=0; i<gnum; i++)
		{
			double x_item=x_step*i+0.2*x_step;

			DefaultMutableTreeNode inode=(DefaultMutableTreeNode) currentnode.getChildAt(0);

			RectObject nt=new RectObject (inode.toString(),scene_2, x_item, 650,150,60);

			// save the allocation
			solution[i]=inode.toString();

			// draw the allocation
			nt.draw();

			currentnode=inode;

		}

		cd.setRisk((float) bid.risk_sl);
		CbrSaving.saveState(cd);
		CbrSaving.saveSolution(solution, cd);
		
		


		gline line1= new gline("Solution generated by Bid Tree",scene_2,130,250,1200);
		gline line2= new gline("Utility="+bid.risk_sl,scene_2,100,360,1200);

		line1.draw();
		line2.draw();

		scene_2.refresh();


		tabbedPane.setSelectedIndex(4);
	}






	/**
	 * 
	 * thread start action
	 * 
	 * */
	private void startAll(){
		tabbedPane.setSelectedIndex(6);
		tcp.allStart();
	}


	/**
	 * 
	 * thread stop action 
	 * 
	 * */

	private void stopAll(){

		tcp.allStop();
	}


	// expand all path for a JTree
	private void expandAll(JTree tree, TreePath parent, boolean expand) {
		// Traverse children
		DefaultMutableTreeNode node = (DefaultMutableTreeNode)parent.getLastPathComponent();
		if (node.getChildCount() >= 0) {
			for (Enumeration e=node.children(); e.hasMoreElements(); ) {
				DefaultMutableTreeNode n = (DefaultMutableTreeNode)e.nextElement();
				TreePath path = parent.pathByAddingChild(n);
				expandAll(tree, path, expand);
			}
		}

		// Expansion or collapse must be done bottom-up
		if (expand) {
			tree.expandPath(parent);
		} else {
			tree.collapsePath(parent);
		}
	}


}
